package context.render.tiu.texture;

import context.util.Data;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.ByteBuffer;
import javax.imageio.ImageIO;
import math.math;
import math.vec2i;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
import org.lwjgl.opengl.GL30;

public class TexturePNG extends Texture
{

    public static final String FILE_PATH = "images/";

    public static final String FILE_TYPE = ".png";
    
    
    public TexturePNG(String aFileName)
    {
        // Generate an OpenGL ID via the super-class's constructor:
        super(vec2i.ZERO);
        // Now load the image properly:
        String fullPath = (
            TexturePNG.FILE_PATH + 
            aFileName + 
            TexturePNG.FILE_TYPE
        );
        BufferedImage image = this.loadImage(fullPath);
        // Set the size correctly:
        vec2i size = new vec2i(image.getWidth(), image.getHeight());
        this.mSize.set(size);
        // Send the image data to the GPU:
        ByteBuffer imageData = this.getByteBufferOf(image);
        GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.mID);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL14.GL_GENERATE_MIPMAP, GL11.GL_TRUE);
        GL11.glTexImage2D(
            GL11.GL_TEXTURE_2D, 
            0, 
            GL11.GL_RGBA8, 
            size.x, 
            size.y, 
            0, 
            GL11.GL_RGBA, 
            GL11.GL_UNSIGNED_BYTE, 
            imageData
        );
        GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
        
    }
    
    
    
    
    private BufferedImage loadImage(String aFullPath) 
    {
        BufferedImage image = null;
        try
        {
            image = ImageIO.read(new File(aFullPath));
        }
        catch (Exception e)
        {
            System.err.println("Failure loading image: " + aFullPath);
            System.exit(1);
        }
        return image;
    }
    
    
    private ByteBuffer getByteBufferOf(BufferedImage aImage) 
    {
        int index = 0;
        int numBytes = 4 * aImage.getHeight() * aImage.getWidth();
        byte[] byteArr = new byte[numBytes];
//        for (int y = aImage.getHeight() - 1; y >= 0; y--)
        for (int y = 0; y < aImage.getHeight(); y++)
        for (int x = 0; x < aImage.getWidth(); x++) 
        {
            // Grab pixel data from the image:
            int argb = aImage.getRGB(x, y);
            // Unpack pixel data from ARGB format:
            int a = (argb >> 24) & 0xFF;
            int r = (argb >> 16) & 0xFF;
            int g = (argb >> 8) & 0xFF;
            int b = argb & 0xFF;
//            final double exp = 1.0 / 2.2;
            final double exp = 1.0;
            byte ab = (byte)(math.powd(a / 255.0, exp) * 255);
            byte rb = (byte)(math.powd(r / 255.0, exp) * 255);
            byte gb = (byte)(math.powd(g / 255.0, exp) * 255);
            byte bb = (byte)(math.powd(b / 255.0, exp) * 255);
            // Pack pixel data into RGBA format:
            byteArr[index++] = rb;
            byteArr[index++] = gb;
            byteArr[index++] = bb;
            byteArr[index++] = ab;
        }
        ByteBuffer byteBuffer = Data.get().asByteBuffer(byteArr);
        return byteBuffer;
    }
    
}
